from flask import request, jsonify, g
from flask_jwt_extended import jwt_required
import datetime
from bson import ObjectId

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required
from app.schemas.department import DepartmentSchema, DepartmentUpdateSchema
from app.utils.common import normalize_data, paginate

@api_bp.route('/departments', methods=['GET'])
@jwt_required()
def get_departments():
    """获取科室列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'order')
    order = request.args.get('order', 'asc')
    
    # 构建查询条件
    query = {}
    
    # 按名称搜索
    name = request.args.get('name')
    if name:
        query['name'] = {'$regex': name, '$options': 'i'}
    
    # 按类别筛选
    category = request.args.get('category')
    if category and category != 'all':
        query['category'] = category
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 确定排序
    sort_direction = 1 if order.lower() == 'asc' else -1
    
    # 获取数据
    departments_cursor = mongo.db.departments.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(departments_cursor, page, limit)
    
    # 标准化数据
    departments = []
    for department in paginated_data['items']:
        normalized_department = normalize_data(department)
        
        # 获取科室主任信息
        if 'headDoctor' in department and department['headDoctor']:
            head_doctor_id = department['headDoctor']
            if ObjectId.is_valid(head_doctor_id):
                doctor = mongo.db.doctors.find_one({'_id': ObjectId(head_doctor_id)})
                if doctor:
                    normalized_department['headDoctorName'] = doctor.get('name', '')
        
        # 获取科室医生数量
        doctor_count = mongo.db.doctors.count_documents({
            'departmentId': str(department['_id']),
            'status': '在职'
        })
        normalized_department['doctorCount'] = doctor_count
        
        departments.append(normalized_department)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'departments': departments
        }
    }), 200

@api_bp.route('/departments', methods=['POST'])
@jwt_required()
@permission_required('department:create')
def create_department():
    """创建新科室"""
    # 验证请求数据
    schema = DepartmentSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 检查科室编码是否已存在
    if mongo.db.departments.find_one({'code': data['code']}):
        return jsonify({
            'success': False,
            'message': '该科室编码已存在'
        }), 400
    
    # 检查科室名称是否已存在
    if mongo.db.departments.find_one({'name': data['name']}):
        return jsonify({
            'success': False,
            'message': '该科室名称已存在'
        }), 400
    
    # 检查科室主任
    if 'headDoctor' in data and data['headDoctor']:
        head_doctor_id = data['headDoctor']
        if not mongo.db.doctors.find_one({'_id': ObjectId(head_doctor_id)}):
            return jsonify({
                'success': False,
                'message': '科室主任不存在'
            }), 400
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    
    # 保存到数据库
    result = mongo.db.departments.insert_one(data)
    
    return jsonify({
        'success': True,
        'message': '科室创建成功',
        'data': {
            'id': str(result.inserted_id),
            'code': data['code'],
            'name': data['name'],
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/departments/<id>', methods=['GET'])
@jwt_required()
def get_department(id):
    """获取单个科室详情"""
    # 尝试按ID查找
    department = None
    
    # 如果是有效的ObjectId，按_id查找
    if ObjectId.is_valid(id):
        department = mongo.db.departments.find_one({'_id': ObjectId(id)})
    
    # 如果没找到，尝试按code查找
    if not department:
        department = mongo.db.departments.find_one({'code': id})
    
    if not department:
        return jsonify({
            'success': False,
            'message': '科室不存在'
        }), 404
    
    # 标准化数据
    normalized_department = normalize_data(department)
    
    # 获取科室主任信息
    head_doctor_info = None
    if 'headDoctor' in department and department['headDoctor']:
        head_doctor_id = department['headDoctor']
        if ObjectId.is_valid(head_doctor_id):
            doctor = mongo.db.doctors.find_one({'_id': ObjectId(head_doctor_id)})
            if doctor:
                head_doctor_info = {
                    'id': str(doctor['_id']),
                    'staffId': doctor.get('staffId', ''),
                    'name': doctor.get('name', ''),
                    'title': doctor.get('title', '')
                }
    normalized_department['headDoctorInfo'] = head_doctor_info
    
    # 获取科室医生列表
    doctors = []
    doctors_cursor = mongo.db.doctors.find({
        'departmentId': str(department['_id']),
        'status': '在职'
    }).sort('name', 1)
    
    for doctor in doctors_cursor:
        doctors.append({
            'id': str(doctor['_id']),
            'staffId': doctor.get('staffId', ''),
            'name': doctor.get('name', ''),
            'title': doctor.get('title', ''),
            'specialties': doctor.get('specialties', [])
        })
    
    normalized_department['doctors'] = doctors
    
    # 获取科室当前可预约信息
    today = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
    one_week_later = today + datetime.timedelta(days=7)
    
    schedules = []
    schedules_cursor = mongo.db.schedules.find({
        'departmentId': str(department['_id']),
        'date': {'$gte': today, '$lte': one_week_later},
        'status': '正常'
    }).sort('date', 1)
    
    for schedule in schedules_cursor:
        doctor_name = ''
        doctor_id = schedule.get('doctorId')
        if doctor_id:
            doctor = mongo.db.doctors.find_one({'_id': ObjectId(doctor_id)})
            if doctor:
                doctor_name = doctor.get('name', '')
        
        schedules.append({
            'id': str(schedule['_id']),
            'date': schedule.get('date'),
            'doctorName': doctor_name,
            'registrationType': schedule.get('registrationType', ''),
            'timeSlots': schedule.get('timeSlots', []),
            'remainingCapacity': schedule.get('remainingCapacity', {})
        })
    
    normalized_department['schedules'] = schedules
    
    return jsonify({
        'success': True,
        'data': normalized_department
    }), 200

@api_bp.route('/departments/<id>', methods=['PUT'])
@jwt_required()
@permission_required('department:update')
def update_department(id):
    """更新科室信息"""
    # 验证请求数据
    schema = DepartmentUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 查找科室
    department = None
    if ObjectId.is_valid(id):
        department = mongo.db.departments.find_one({'_id': ObjectId(id)})
    
    if not department:
        department = mongo.db.departments.find_one({'code': id})
    
    if not department:
        return jsonify({
            'success': False,
            'message': '科室不存在'
        }), 404
    
    # 如果更新科室名称，检查是否与其他科室重名
    if 'name' in data and data['name'] != department['name']:
        conflict = mongo.db.departments.find_one({'name': data['name'], '_id': {'$ne': department['_id']}})
        if conflict:
            return jsonify({
                'success': False,
                'message': '科室名称已存在'
            }), 400
    
    # 检查科室主任
    if 'headDoctor' in data and data['headDoctor']:
        head_doctor_id = data['headDoctor']
        if not mongo.db.doctors.find_one({'_id': ObjectId(head_doctor_id)}):
            return jsonify({
                'success': False,
                'message': '科室主任不存在'
            }), 400
    
    # 准备更新数据
    update_data = data.copy()
    update_data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    result = mongo.db.departments.update_one(
        {'_id': department['_id']},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '科室信息更新失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '科室信息更新成功',
        'data': {
            'id': str(department['_id']),
            'code': department['code'],
            'name': data.get('name', department['name']),
            'updatedAt': update_data['updatedAt'].isoformat()
        }
    }), 200

@api_bp.route('/departments/<id>', methods=['DELETE'])
@jwt_required()
@permission_required('department:delete')
def delete_department(id):
    """删除科室（或标记为禁用）"""
    # 查找科室
    department = None
    if ObjectId.is_valid(id):
        department = mongo.db.departments.find_one({'_id': ObjectId(id)})
    
    if not department:
        department = mongo.db.departments.find_one({'code': id})
    
    if not department:
        return jsonify({
            'success': False,
            'message': '科室不存在'
        }), 404
    
    # 检查是否有医生关联到该科室
    has_doctors = mongo.db.doctors.find_one({'departmentId': str(department['_id'])})
    
    # 检查是否有排班关联到该科室
    has_schedules = mongo.db.schedules.find_one({'departmentId': str(department['_id'])})
    
    # 检查是否有医疗记录关联到该科室
    has_records = mongo.db.medical_records.find_one({'departmentId': str(department['_id'])})
    
    # 如果有关联记录，只将科室标记为禁用
    if has_doctors or has_schedules or has_records:
        result = mongo.db.departments.update_one(
            {'_id': department['_id']},
            {
                '$set': {
                    'status': '禁用',
                    'updatedAt': datetime.datetime.utcnow()
                }
            }
        )
        
        if result.modified_count == 0:
            return jsonify({
                'success': False,
                'message': '科室状态更新失败'
            }), 500
        
        return jsonify({
            'success': True,
            'message': '科室已标记为禁用',
            'data': None
        }), 200
    
    # 如果没有关联记录，可以真正删除
    result = mongo.db.departments.delete_one({'_id': department['_id']})
    
    if result.deleted_count == 0:
        return jsonify({
            'success': False,
            'message': '科室删除失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '科室删除成功',
        'data': None
    }), 200

@api_bp.route('/departments/categories', methods=['GET'])
@jwt_required()
def get_department_categories():
    """获取科室类别列表"""
    categories = ['临床', '医技', '行政', '其他']
    return jsonify({
        'success': True,
        'data': {
            'categories': categories
        }
    }), 200 